package com.bbz.core.lambda.java8.Chapter_7_parallel;

import java.util.stream.DoubleStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;

/**
 * 用传统方式,java8 顺序流方式,java8 并行流方式分别实现对自然数求和
 */
public class ParallelStreams {

    /**
     * 传统方式
     * @param n
     * @return
     */
    public static long iterativeSum(long n) {
        long result = 0;
        for (long i = 1L; i <= n; i++) {
            result += i;
        }
        return result;
    }


    /**
     * java 8 顺序流方式
     * ***Stream.iterate 方式生成的是装箱的对象，每一次计算都需要拆箱。所以运行速度不近人意
     * @param n
     * @return
     */
    public static long sequentialSum(long n) {
        return Stream.iterate(1L, i -> i + 1)
                .limit(n)
                .reduce(0L, Long::sum);
    }

    /**
     * java 8 并行流方式
     * @param n
     * @return
     */
    public static long parallelSum(long n){
        return Stream.iterate(1L,i->i+1)
                .limit(n)
                .parallel()
                .reduce(0L,Long::sum);
    }


    /**
     * java 8 顺序流 使用LongStream.rangClosed 方式求和
     */
    public static long rangedSum(long n) {
        return LongStream.rangeClosed(1, n)
                .reduce(0L, Long::sum);
    }

    /**
     * java 8 并行流 使用LongStream.rangClosed 方式求和
     */
    public static long parallelRangedSum(long n) {
        return LongStream.rangeClosed(1, n)
                .parallel()
                .reduce(0L, Long::sum);
    }

    public static long sideEffectSum(long n){
        Accumulator accumulator=new Accumulator();
        LongStream.rangeClosed(1,n).parallel().forEach(accumulator::add);
        return accumulator.total;
    }

    public static class Accumulator {
        public long total = 0;
        public void add(long value) { total += value; }
    }
}
